[% setvar title docs/pdds/pdd03_calling_conventions.pod - Parrot Calling Conventions %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='NAME'></a><h1>NAME</h1>
<p>docs/pdds/pdd03_calling_conventions.pod - Parrot Calling Conventions</p>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>This PDD describes Parrot's inter-routine calling conventions.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>Please note that the following conventions are <i>only</i> necessary when
exposing subs and methods via the generic parrot routine exposure
mechanism. What does this mean?</p>
<p>It means the caller needs to follow these conventions <i>only</i> when
calling into subs and methods that it has looked up symbolically via
parrot's default lookup system. If a language has a lighter-weight
calling mechanism that's safe to use in some circumstances, it's
perfectly fine to use that.</p>
<p>This means that if you write a C compiler that targets Parrot, for
example, you don't need to use parrot's caller-save, full-on calling
conventions when one C function calls another if the compiler knows
at compile (or possibly link) time what parameters are being passed
into the function.</p>
<p>This can potentially save a significant amount of time when dealing
with languages that are fully, or nearly fully, bound at compile
time, and especially when dealing with languages, such as Forth, that
would otherwise spend an inordinate amount of time calling small
functions.</p>
<p>If a function isn't exposed at all, it doesn't need to have any way
to call into it with the standard calling conventions. It's also
perfectly acceptable for there to be two ways to call into a
function--one with a language's private calling method, and another
that follows the standard conventions.</p>
<p>When this document refers to an &quot;array PMC&quot;, used for passing
overflow parameters in and out, this means a PMC that can be accessed
by integer index and which can return its length. It doesn't need to
be of any particular class, it just needs to <i>act</i> like an
array. It specifically does <i>not</i> need to be able to extend itself,
and may be considered (and actually be) a constant array.</p>
<p>Since Parrot's calling conventions are continuation-based, there is
arguably very little difference between a call and a return. Because
of this, the registers are set the same regardless of whether code is
invoking a subroutine or a return continuation.</p>
<p>Please note that, in the interest of speed, there is a count-free
version of sub calling. This mechanism should only be used when
calling a static subroutine (never a method) with a fixed-arg-count
signature that is known at compile time and guaranteed not to
change. It should not be used when writing code for/in dynamic
languages.</p>
<a name='Responsibility for environment preservation'></a><h2>Responsibility for environment preservation</h2>
<p>Parrot uses a fully continuation passing style for control flow. As
such there is no 'return' environment as such. The object being
invoked is responsible for any saving of registers -- parrot itself
makes no guarantees here.</p>
<p>The return continuation PMC type, used to create return continuations
used for call/return style programming, guarantees that registers
16-31 for all types (P, N, S, and I) will be set such that the
contents of those registers are identical to the content of the
registers when the return continuation was <i>created</i>. Note that if a
return continuation object is created explicitly, rather than by an
invocation op, the preserved registers will be in the state they were
at the time the continuation was made, rather than the state they were
at the time the continuation was passed into an invocation.</p>
<a name='Calling conventions'></a><h2>Calling conventions</h2>
<p>The following registers are used in calling all subs and methods. The
registers must be set by the <i>caller</i>, either explicitly or
implicitly. (Implicit setting of these registers may be done by ops
which document they do so. For example the callcc op notes that it
creates and provides a return continuation) Some, but not all, of the
registers are passed in to the callee. Parrot does, however, consume
some of these values.</p>
<p>Note that registers 16-31 of each of the four types are, for security
reasons, <i>never</i> passed into the invoked subroutine, method, or
continuation. They are guaranteed to be garbage.</p>
<p>The registers as set up by the <i>caller</i>:</p>
<ul>
<li><a name='P0'></a>P0</li>
<p>Holds the object representing the subroutine.</p>
<li><a name='P1'></a>P1</li>
<p>Holds the return continuation for the caller.</p>
<li><a name='P2'></a>P2</li>
<p>Holds the object the sub was called on. (For method calls)</p>
<li><a name='P3'></a>P3</li>
<p>The overflow parameters. Everything that wouldn't fit in a register
is in here. This PMC should act as an array, and belongs to the
called sub/function/method. The caller should not assume anything
about the state of the PMC passed in here after the call is made.</p>
<li><a name='S0'></a>S0</li>
<p>The fully qualified name of the method or sub being called</p>
<li><a name='I0'></a>I0</li>
<p>1 if the sub is being called with fully prototyped parameters,
including P/I/S/N counts.</p>
<p>0 if all the parameters are jammed in P registers and the overflow
array, with a count of parameters passed in PMC registers</p>
<p>-1 if the count registers aren't filled in.</p>
<li><a name='I1'></a>I1</li>
<p>The number of params in integer registers</p>
<li><a name='I2'></a>I2</li>
<p>The number of string parameters</p>
<li><a name='I3'></a>I3</li>
<p>The number of parameters in PMC registers.</p>
<li><a name='I4'></a>I4</li>
<p>The number of numeric parameters</p>
</ul>
<p>The following registers, with the exception of P registers, are used
<i>only</i> when calling a subroutine for which there is a compile-time
prototype. The first 11 PMC parameters may be passed in registers P5
through P15.</p>
<ul>
<li><a name='I5 through I15'></a>I5 through I15</li>
<p>The first 11 integer parameters.</p>
<li><a name='S5 through S15'></a>S5 through S15</li>
<p>The first 11 string parameters.</p>
<li><a name='N5 through N15'></a>N5 through N15</li>
<p>The first 11 numeric parameters.</p>
<li><a name='P5 through P15'></a>P5 through P15</li>
<p>The first 11 PMC parameters.</p>
</ul>
<p>Overflow parameters go in the array PMC passed in P3. Overflow
entries are in there in order, so element 0 is the first overflow
parameter, element 1 the second, and so on.</p>
<p>The PMC for a hash, array, or list is passed if one of the entries in
the parameter list is a hash, array, or list. The aggregate is <b>not</b>
flattened. (Though when accessing the parameters it may be)</p>
<p>Parameters are passed in S, I, and N registers only if the sub's
prototype specifically indicates it takes parameters of that type. I0
must be set to 1 if that is the case. If I0 is 0, then the S, I, and
N registers can be assumed to be garbage.</p>
<p>Note that it doesn't matter what the order of the integer, string,
numeric, and PMC parameters are in the parameter list up until
overflow occurs. Once overflow occurs the parameters must be taken in
the exact order that they appear in the signature.</p>
<p>The registers of the above set as seen by the callee are:</p>
<ul>
<li><a name='P3'></a>P3</li>
<p><i>Only</i> if there are overflow parameters. Otherwise garbage</p>
<li><a name='S0'></a>S0</li>
<li><a name='I0'></a>I0</li>
<li><a name='I1-I4'></a>I1-I4</li>
<p><i>Only</i> if I0 indicates that a prototyped call was made. Otherwise garbage</p>
<li><a name='used parameter registers P5 through P15'></a>used parameter registers P5 through P15</li>
<li><a name='used parameter registers I5 through I15'></a>used parameter registers I5 through I15</li>
<li><a name='used parameter registers S5 through S15'></a>used parameter registers S5 through S15</li>
<li><a name='used parameter registers N5 through N15'></a>used parameter registers N5 through N15</li>
</ul>
<p>Note particularly that P0-P2 are not passed. They are consumed by
Parrot and placed into the interpreter structure, and may be fetched
with the interpinfo op if necessary. Fetching the return continuation
may be expensive, and should only be done if truly necessary.</p>
<p>The <i>callee</i> must assume that any unused registers are garbage. This
includes registers which could hold a parameter but don't due to lack
of parameters. (For example, if only one PMC parameter is passed then
PMC registers 6-15 are garbage)</p>
<a name='Prototyped parameters'></a><h2>Prototyped parameters</h2>
<p>A sub or method can be called in two ways--either prototyped or
non-prototyped.</p>
<p>A prototyped call means that the caller has an idea of what
parameters the sub takes, and has placed its parameters in the
appropriate S, I, N, and P registers. I0 will be true in this case.</p>
<p>An unprototyped call means the caller doesn't know what the sub
takes, so has stuffed all its parameters into PMCs, and put those
PMCs first in the PMC registers with any overflow in the overflow
array. I0 will be false in this case.</p>
<p>The sub being called is responsible for runtime checking the parameter
types to see if there is a parameter mismatch problem, if it
cares. (Often it doesn't) This isn't a replacement for that sort of
parameter type checking. What it is, instead, is a means of allowing
shortcutting parameter placement checking for the called sub.</p>
<p>For example, assume we have a subroutine with a signature that looks
like:</p>
<pre>    sub foo(int a, int b, string c, PMC d, float e);</pre>
<p>If we were calling without prototyping, all five parameters would be
passed in as PMCs, in registers P5 through P9. If, on the other hand,
we were calling with prototyping, a would be in I5, b in I6, c in S5,
d in P5, and e in N5.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>None.</p>
<a name='VERSION'></a><h1>VERSION</h1>
<p>1.4</p>
<a name='CURRENT'></a><h2>CURRENT</h2>
<pre>    Maintainer: Dan Sugalski
    Class: Internals
    PDD Number: 03
    Version: 1.4
    Status: Developing
    Last Modified: 17 November 2003
    PDD Format: 1
    Language: English</pre>
<a name='HISTORY'></a><h2>HISTORY</h2>
<ul>
<li><a name='Version 1.4'></a>Version 1.4</li>
<p>17 November 2003</p>
<li><a name='Version 1.3'></a>Version 1.3</li>
<p>2 May 2003</p>
<li><a name='Version 1,2'></a>Version 1,2</li>
<p>11 March 2003</p>
<li><a name='Version 1.1'></a>Version 1.1</li>
<p>16 September 2002</p>
<li><a name='version 1'></a>version 1</li>
<p>None. First version</p>
</ul>
<a name='CHANGES'></a><h1>CHANGES</h1>
<ul>
<li><a name='Version 1.4'></a>Version 1.4</li>
<p>Unified call and return, tossed useless stuff</p>
<li><a name='Version 1.3'></a>Version 1.3</li>
<p>No longer use the stack, with overflow going into the array in P3.</p>
<p>Clarified some muddy language.</p>
<li><a name='Version 1.2'></a>Version 1.2</li>
<p>Dropped the number of registers passed in and out of subs.</p>
<li><a name='Version 1.1'></a>Version 1.1</li>
<p>We now call with a frame, rather than pushing on the stack, and we
return frames, rather than returning a stack. We also pass in context
information for the return.</p>
<li><a name='Version 1.0'></a>Version 1.0</li>
<p>None. First version</p>
</ul>
</div>
